//
//  CLReadLongPressView.m
//  CLBrowser
//
//  Created by 梁慧聪 on 2022/8/15.
//

#import "CLReadLongPressView.h"
#import "CLCoreText.h"
@implementation CLReadLongPressView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        UILongPressGestureRecognizer *longGes = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longAction:)];
        self.longGes = longGes;
        [self addGestureRecognizer:longGes];
        
        UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
        self.tapGes = tapGes;
        tapGes.enabled = NO;
        [self addGestureRecognizer:tapGes];
    }
    return self;
}

/// 创建放大镜
- (void)creatMagnifierView:(CGPoint)windowPoint {
    
    if (_magnifierView == nil) {
        
        CLMagnifierView *magnifierView = [[CLMagnifierView alloc]init];
        self.magnifierView = magnifierView;
        magnifierView.targetWindow = self.window;
        magnifierView.targetPoint = windowPoint;
    }
}
// MARK: 手势事件

/// 单击事件
- (void)tapAction:(UITapGestureRecognizer *)longGes {
    // 重置页面数据
    [self reset];
}

- (void)longAction:(UILongPressGestureRecognizer *)longGes {
    WEAK_SELF;
    // 触摸位置
    CGPoint point = [longGes locationInView:self];

    // 触摸位置
    CGPoint windowPoint = [longGes locationInView:self.window];

    // 触摸开始 触摸中
    if (longGes.state == UIGestureRecognizerStateBegan) {

        // 发送通知z
        CL_READ_NOTIFICATION_PUSH(@{CL_READ_KEY_LONG_PRESS_VIEW:@(YES)});

        // 放大镜
        [self creatMagnifierView:windowPoint];

    }else if (longGes.state == UIGestureRecognizerStateChanged) {

        // 设置放大镜位置
        self.magnifierView.targetPoint = windowPoint;

    }else{ // 触摸结束

        // 获得选中区域
        self.selectRange = [CLCoreText getTouchParagraphRange:point frameRef:self.frameRef content:self.pageModel.content.string];

        // 获得选中选中范围
        self.rects = [CLCoreText getRangeRects:self.selectRange frameRef:self.frameRef content:self.pageModel.content.string];

        // 显示光标
        [self cursor:YES];

        // 设置放大镜位置
        self.magnifierView.targetPoint = windowPoint;

        // 移除
        [self.magnifierView remove:^{
            
            // 清空
            weakSelf.magnifierView = nil;
            
            // 显示菜单
            [weakSelf showMenu:YES];
        }];
       

        // 重绘
        [self setNeedsDisplay];

        // 开启手势
        if (self.rects && !self.rects.isEmpty) {

            // 手势状态
            longGes.enabled = NO;
            self.tapGes.enabled = YES;
            self.isOpenDrag = YES;

            // 发送通知
            CL_READ_NOTIFICATION_PUSH(@{CL_READ_KEY_LONG_PRESS_VIEW : @(NO)});
        }
    }
}

// MARK: 页面触摸拖拽处理

/// 触摸开始
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self drag:touches status:CLPanGesStatusBegin];
}

/// 触摸移动
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self drag:touches status:CLPanGesStatusChanged];
}

/// 触摸结束
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self drag:touches status:CLPanGesStatusEnd];
}

/// 触摸取消
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self drag:touches status:CLPanGesStatusEnd];
}

/// 解析触摸事件
- (void)drag:(NSSet<UITouch *> *)touches status:(CLPanGesStatus)status {
    
    if (self.isOpenDrag) {
        
        UITouch *touch= touches.anyObject;
        
        CGPoint point = [touch locationInView:self];
        
        CGPoint windowPoint = [touch locationInView:self.window];
        
        [self drag:status point:point windowPoint:windowPoint];
    }
}

/// 拖拽事件解析
- (void)drag:(CLPanGesStatus)status point:(CGPoint)point windowPoint:(CGPoint)windowPoint {
    WEAK_SELF;
    // 检查是否超出范围
    point = CGPointMake(MIN(MAX(point.x, 0), self.pageModel.contentSize.width), MIN(MAX(point.y, 0), self.pageModel.contentSize.height));

    // 触摸开始
    if (status == CLPanGesStatusBegin) {
        
        if (CGRectContainsPoint(CGRectInset(self.LCursorView.frame, CL_READ_LONG_PRESS_CURSOR_VIEW_OFFSET, CL_READ_LONG_PRESS_CURSOR_VIEW_OFFSET), point)){ // 触摸到左边光标
            
            // 隐藏菜单
            [self showMenu:NO];
            
            _isCursorLorR = YES;
            
            _isTouchCursor = YES;
            
        
        
        }else if (CGRectContainsPoint(CGRectInset(self.RCursorView.frame, CL_READ_LONG_PRESS_CURSOR_VIEW_OFFSET, CL_READ_LONG_PRESS_CURSOR_VIEW_OFFSET), point)) { // 触摸到右边光标
            
            // 隐藏菜单
            [self showMenu:NO];
            
            _isCursorLorR = NO;
            
            _isTouchCursor = YES;
            
        }else{ // 没有触摸到光标
            
            _isTouchCursor = NO;
        }
        
        // 触摸到了光标
        if (_isTouchCursor) {
            
            // 放大镜
            [self creatMagnifierView:windowPoint];
        }
        
    }else if (status == CLPanGesStatusChanged) { // 触摸中
     
        // 触摸到光标
        if (_isTouchCursor) {
            
            // 设置放大镜位置
            _magnifierView.targetPoint = windowPoint;
        }
        
        // 判断触摸
        if (_isTouchCursor && _selectRange.location +_selectRange.length > 0) {
            
            // 触摸到的位置
            CFIndex location = [CLCoreText getTouchLocation:point frameRef:self.frameRef];
            
            // 无结果
            if (location == -1) { return; }
         
            // 刷新选中区域:
            [self updateSelectRange:location];

            
            // 获得选中选中范围
            self.rects = [CLCoreText getRangeRects:self.selectRange frameRef:self.frameRef content:self.pageModel.content.string];
            
            // 更新光标位置
            [self updateCursorFrame];
        }
        
    }else{ // 触摸结束

        // 触摸到光标
        if (self.isTouchCursor) {
            
            // 设置放大镜位置
            self.magnifierView.targetPoint = windowPoint;
            
            // 移除
            [self.magnifierView remove:^{
                // 清空
                weakSelf.magnifierView = nil;
                
                // 显示菜单
                [weakSelf showMenu:YES];
            }];
            
            
        }
        
        // 结束触摸
        _isTouchCursor = NO;
    }
    
    // 重绘
    [self setNeedsDisplay];
}
//
///// 刷新选中区域
- (void)updateSelectRange:(NSInteger) location {

    // 左右 Location 位置
    NSUInteger LLocation = self.selectRange.location;
    NSUInteger RLocation = self.selectRange.location + self.selectRange.length;

    // 判断触摸
    if (self.isCursorLorR) { // 左边

        if (location < RLocation) {

            if (location > LLocation) {
                
                self.selectRange = NSMakeRange(location, self.selectRange.length - (location + LLocation));
                
            }else if (location < LLocation) {
                
                self.selectRange = NSMakeRange(location, self.selectRange.length + (location - LLocation));

            }

        }else{

            self.isCursorLorR = NO;

            NSUInteger length = location - RLocation;

            NSUInteger tempLength = (length == 0 ? 1 : 0);

            length = (length == 0 ? 1 : length);

            self.selectRange = NSMakeRange(RLocation - tempLength, length);

            [self updateSelectRange:location];
        }

    }else{ // 右边

        if (location > LLocation) {

            if (location > RLocation) {

                self.selectRange = NSMakeRange(self.selectRange.location, self.selectRange.length + (location - RLocation));

            }else if (location < RLocation) {

                self.selectRange = NSMakeRange(self.selectRange.location, self.selectRange.length - (RLocation - location));

            }

        }else{

            self.isCursorLorR = YES;

            NSUInteger tempLength = LLocation - location;

            NSUInteger length = (tempLength == 0 ? 1 : tempLength);

            self.selectRange = NSMakeRange(LLocation - tempLength, length);
            
            [self updateSelectRange:location];
        }
    }
}

// MARK: 光标处理

/// 隐藏或显示光标
- (void)cursor:(BOOL)isShow {
    if (isShow) {
        
        if (self.rects && !self.rects.isEmpty && _LCursorView == nil) {
            
            CLReadLongPressCursorView *LCursorView = [[CLReadLongPressCursorView alloc]init];
            self.LCursorView = LCursorView;
            LCursorView.isTorB = YES;
            [self addSubview:LCursorView];
            
            CLReadLongPressCursorView *RCursorView = [[CLReadLongPressCursorView alloc]init];
            self.RCursorView = RCursorView;
            RCursorView.isTorB = NO;
            [self addSubview:RCursorView];
            
            [self updateCursorFrame];
        }
        
    }else{
        
        if (_LCursorView != nil) {
            
            [_LCursorView removeFromSuperview];
            _LCursorView = nil;
            
            [_RCursorView removeFromSuperview];
            _RCursorView = nil;
        }
    }
}

- (void)updateCursorFrame {
    if (self.rects && !self.rects.isEmpty && _LCursorView != nil) {
        
        CGFloat cursorViewW = 10;
        CGFloat cursorViewSpaceW = cursorViewW / 4.0;
        CGFloat cursorViewSpaceH = cursorViewW / 1.1;
        CGRect first = [self.rects.firstObject CGRectValue];
        CGRect last = [self.rects.lastObject CGRectValue];
        
        _LCursorView.frame = CGRectMake(CGRectGetMinX(first) - cursorViewW + cursorViewSpaceW, self.bounds.size.height - CGRectGetMinY(first) - first.size.height - cursorViewSpaceH, cursorViewW, first.size.height + cursorViewSpaceH);
        
        _RCursorView.frame = CGRectMake(CGRectGetMaxX(last) - cursorViewSpaceW, self.bounds.size.height - CGRectGetMinY(last) - last.size.height, cursorViewW, last.size.height + cursorViewSpaceH);
    }
}

// MARK: 重置页面

/// 重置页面数据
- (void)reset {
    WEAK_SELF;
    // 发送通知
    CL_READ_NOTIFICATION_PUSH(@{CL_READ_KEY_LONG_PRESS_VIEW : @(YES)});
    
    // 手势状态
    self.tapGes.enabled = NO;
    self.isOpenDrag = NO;
    self.longGes.enabled = YES;
    
    // 移除菜单
    [self showMenu: NO];
    
    // 清空选中
    self.selectRange = NSMakeRange(0, 0);
    self.rects = @[];
    
    // 移除光标
    [self cursor: NO];
    
    // (如果有放大镜)移除放大镜
    [self.magnifierView remove:^{
        // 清空
        weakSelf.magnifierView = nil;
    }];
    
    // 重绘
    [self setNeedsDisplay];
}

// MARK: 菜单相关

/// 隐藏或显示菜单
- (void)showMenu:(BOOL)isShow {
    
    if (isShow) { // 显示
        
        if (self.rects && !self.rects.isEmpty) {
            
            CGRect rect = [CLCoreText getMenuRect:self.rects viewFrame:self.bounds];
            
            [self becomeFirstResponder];
            
            UIMenuController *menuController = UIMenuController.sharedMenuController;
            
            UIMenuItem *copy = [[UIMenuItem alloc]initWithTitle:@"复制" action:@selector(clickCopy)];
            
            menuController.menuItems = @[copy];
            
            [menuController setTargetRect:rect inView:self];
            
            DelayDefaultHandle(^{
                [menuController setMenuVisible: YES];
            });
            
        }
        
    }else{ // 隐藏
        
        DelayDefaultHandle (^{
            [UIMenuController.sharedMenuController setMenuVisible:NO];
        });
    }
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    
    if (action == @selector(clickCopy)) {
        return YES;
    }
    return NO;
    
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (void)clickCopy {
    
    if (self.selectRange.location + self.selectRange.length > 0) {
        
        NSRange temSelectRange = self.selectRange;
        
        NSAttributedString *tempContent = self.pageModel.content;
        
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            UIPasteboard.generalPasteboard.string = [tempContent.string substringWithRange:temSelectRange];
        });
        
        // 重置页面数据
        [self reset];
    }
}

// MARK: 绘制

/// 绘制
- (void)drawRect:(CGRect)rect {
//    [super drawRect:rect];
    
    if (self.frameRef == nil) {return;}
    
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    CGContextSetTextMatrix(ctx, CGAffineTransformIdentity);
    CGContextTranslateCTM(ctx, 0, self.bounds.size.height);
    CGContextScaleCTM(ctx, 1.0, -1.0);

    if (self.selectRange.location + self.selectRange.length > 0 && self.rects && !self.rects.isEmpty) {
        
        CGMutablePathRef path = CGPathCreateMutable();
        
        CGContextSetFillColorWithColor(ctx, [CL_READ_COLOR_MAIN colorWithAlphaComponent:0.5].CGColor);
        NSUInteger count = self.rects.count;
        CGRect *rects = (CGRect *)malloc((count + 1) * sizeof(CGRect));
        for (unsigned i = 0; i < count; i++) {
            rects[i] = [[self.rects objectAtIndex:i] CGRectValue];
        }
        CGPathAddRects(path, 0, rects, count);
        
        CGContextAddPath(ctx, path);
        
        CGContextFillPath(ctx);
    }
    
    CTFrameDraw(self.frameRef, ctx);
}

- (void)dealloc {
    [self.tapGes removeTarget:self action:@selector(tapAction:)];
    self.tapGes = nil;
    
    [self.longGes removeTarget:self action:@selector(longAction:)];
    self.longGes = nil;
}
@end
